为什么需要安全通信
云函数 URL 化后,接口地址是公开的。任何人拿到 URL 都能直接发起请求,这在生产环境中是不可接受的。uni-cloud-s2s 插件提供了两种安全通信方案:
| 方案 | 复杂度 | 安全级别 | 适用场景 |
|---|---|---|---|
| Token 校验 | 简单 | 中等 | 内部系统间通信 |
| 数据签名校验 | 复杂 | 高 | 对外开放接口 |
方案一:Token 校验
安装插件
在 DCloud 插件市场搜索 uni-cloud-s2s,点击"下载插件并导入 HBuilderX",选择目标项目和云服务商。
安装后,uniCloud/cloud-functions/common/ 目录下会多出 uni-cloud-s2s/index.js 模块。
配置密钥
在 uni-config-center 下创建配置文件:
uniCloud/cloud-functions/common/uni-config-center/uni-cloud-s2s/config.json
text
配置内容:
{
"contentToken": "你的随机密钥字符串(建议32位以上)"
}
json
这个 contentToken 就是后续请求中需要携带的校验令牌。
配置完成后必须上传:右键 uni-config-center → 上传公共模块。很多开发者漏掉了这一步,导致请求时报 "contentToken or sign not found" 错误。
关联云对象依赖
在云对象目录中,右键 package.json(或云对象目录) → 管理公共模块或扩展库依赖 → 勾选 uni-cloud-s2s → 确定。
如果不关联依赖,直接 require('uni-cloud-s2s') 会报找不到模块的错误。
获取安全请求头
// 云对象 say-hello
const { getSecureHeaders, verifyHttpInfo } = require('uni-cloud-s2s')
module.exports = {
async c() {
const headers = getSecureHeaders()
return headers
}
}
javascript
调用该接口后,返回的 headers 对象中包含 contentToken 对应的键值对。外部系统请求云函数时,需要在请求头中携带这个键值对。
校验请求合法性
const { verifyHttpInfo } = require('uni-cloud-s2s')
module.exports = {
async c() {
// 获取 HTTP 请求信息(云对象方式)
const httpInfo = this.getHttpInfo()
// 校验请求头中的 token
// 未校验通过会直接抛出错误,后续代码不会执行
verifyHttpInfo(httpInfo)
// 校验通过,执行业务逻辑
return { message: '请求合法' }
}
}
javascript
使用 Bruno 测试
不带请求头的请求会被拒绝:
GET https://xxx.api.aliyun.com/tomark/say-hello/c
→ 报错:contentToken not found in headers
text
带上安全请求头的请求可以通过校验:
GET https://xxx.api.aliyun.com/tomark/say-hello/c
Header: x-server-sign: <getSecureHeaders() 返回的值>
→ 返回正常数据
text
方案二:数据签名校验
签名方案更加安全,但实现也更复杂。核心流程:
- 生成 32 位签名字符串作为密钥
- 使用 HMAC 等算法对请求数据生成签名
- 将签名放入请求头
- 云函数端使用相同算法验证签名
- 设置签名有效期,防止重放攻击
签名方案支持 Node.js 端生成和验证,官方文档提供了 Node.js 的签名生成示例代码。由于签名算法是公开的,任何语言都可以实现签名生成。
双向通信场景
uni-cloud-s2s 支持两种通信方向:
外部服务器 → 云函数
外部服务器发起请求 → 请求头携带 token/签名 → 云函数校验 → 执行业务逻辑
text
云函数 → 外部服务器
云函数发起请求 → 请求头携带 token/签名 → 外部服务器校验 → 返回数据
text
双向通信的校验逻辑相同,区别在于生成签名和验证签名的位置不同。
常见错误排查
| 错误信息 | 原因 | 解决方法 |
|---|---|---|
Cannot find module 'uni-cloud-s2s' | 云对象未关联依赖 | 右键云对象 → 管理依赖 → 勾选 s2s |
contentToken or sign not found | 配置未上传到云端 | 右键 uni-config-center → 上传公共模块 |
contentToken not found in headers | 请求头未携带 token | 使用 getSecureHeaders() 获取正确的请求头 |
Error 400 | 请求参数解析错误 | 检查 GET/POST 参数获取方式是否正确 |
上传配置后需要等待几秒钟让云函数生效,不要急于测试。
↑